const EventEmitter = require('events').EventEmitter;
const mqtt = require('mqtt');
const moment = require('moment');

const topicPrefix = 'haph/das/'
class MqttClient extends EventEmitter {
  constructor(cfg, monitor) {
    super()
    this._cfg = cfg
    this._monitor = monitor;
    const options = {
      keepalive: 60,
      clientId: 'mqttjs_' + cfg.enterpriseNo,
      clean: false, // receive QoS 1 and 2 messages while offline
      reconnecPeriod: 10000, // milliseconds
      username: 'haph',
      password: '000000',
      will: { // send this message automatically when client disconnect badly
        topic: topicPrefix + cfg.enterpriseNo + '/failed',
        payload: cfg.enterpriseNo + ': ',
        qos: 2,
        retain: true
      }
    }

    this._configEidTopic = `${topicPrefix}config/seteid/${cfg.enterpriseNo}`;
    this._configSidTopic = `${topicPrefix}config/setsid/${cfg.enterpriseNo}`;
    this._transTopic = `${topicPrefix}trans/${cfg.enterpriseNo}`;
    this._enterpriseNo = cfg.enterpriseNo;
    this._serialNo = cfg.serialNo;

    this._mqtt = mqtt.connect(`mqtt://${cfg.serverUrl}`, options);
    this._topic = `haph/cep/data/${cfg.enterpriseNo}/${cfg.serialNo}`;
    this._notify = `haph/cep/notify/`;

    this._mqtt.on('connect', () => {
      this._mqtt.subscribe(this._configEidTopic);
      this._mqtt.subscribe(this._configSidTopic);
      this._mqtt.subscribe(this._transTopic);
    })

    this._mqtt.on('message', (topic, message) => {
      if (topic === this._configEidTopic) {
        this.emit('eid', message.toString());
      } else if (topic === this._configSidTopic) {
        this.emit('sid', message.toString());
      } else if (topic === this._transTopic) {
        this.emit('trans');
      }
    })
  }

  modifyDataTopic(enterpriseId) {
    this._topic = `haph/cep/data/${enterpriseId}/${this._cfg.serialNo}`;
    this._enterpriseNo = enterpriseId;
  }

  publish(message, options, callback) {
    if (this.connected) {
      this._monitor.blinkMqtt();
      this._mqtt.publish(this._topic, message, options, callback)
    }
  }

  notify(message, options, callback) {
    if (this.connected) {
      this._monitor.blinkMqtt();
      const topic = `${this._notify}${message}/${this._enterpriseNo}/${this._serialNo}`;
      const now = moment().format('YYYY-MM-DD H:mm:ss')
      this._mqtt.publish(topic, `${now}`, options, callback);
    }

  }

  get connected() {
    return this._mqtt.connected
  }
}

module.exports = MqttClient

if (require.main === module) {
  var mqttClient = new MqttClient()
  setInterval(function () {
    if (mqttClient.connected) {
      mqttClient.publish('samples', {
        qos: 2
      })
    }
  }, 1000)

  // create a sub client to print out msg
  var sub = mqtt.connect('mqtt://localhost:1883')
  sub.on('connect', () => {
    sub.subscribe('haph/das/+/data')
  })
  sub.on('message', (msg) => {
    console.log(`Received: ${msg}`)
  })
}
